/**
 * Copyright (C) 2009 All Rights Reserved
 * @author sebastian chang
 * @brief practice
 */

#include <sys/time.h>

#include "mutex_lock.h"

namespace trident {

mutex_lock_t::mutex_lock_t()
{
    // Empty
}

mutex_lock_t::~mutex_lock_t()
{
    pthread_mutex_destroy(&_mutex);
}

int mutex_lock_t::init(void* arg_)
{
    return pthread_mutex_init(&_mutex, static_cast<pthread_mutexattr_t*>(arg_)) ? errno : 0;
}

int mutex_lock_t::lock()
{
    return pthread_mutex_lock(&_mutex) ? errno : 0;
}

int mutex_lock_t::unlock()
{
    return pthread_mutex_unlock(&_mutex) ? errno : 0;
}

int mutex_lock_t::trylock()
{
    return pthread_mutex_trylock(&_mutex) ? errno : 0;
}

int mutex_lock_t::timeWait(unsigned long timeout_)
{
    static const unsigned long THOUSAND = 1000;
    static const unsigned long MILLITHOUSAND = 1000000;

    struct timeval tv;
    gettimeofday(&tv, 0);

    struct timespec ts;
    ts.tv_sec = tv.tv_sec;
    ts.tv_nsec = tv.tv_usec * THOUSAND;

    if (0 < timeout_)
    {
        ts.tv_sec += (timeout_ / THOUSAND);
        ts.tv_nsec += (timeout_ % THOUSAND) * MILLITHOUSAND;
    }

    return pthread_mutex_timedlock(&_mutex, &ts) ? errno : 0;
}

} // namespace trident

